﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Base;
using svnAccessFile;
using System.Text.RegularExpressions;

namespace ApacheConfFile
{
    

    public class ApacheConf
    {
        public Locations locations{get;set;}
        private string path;
        public ApacheConf(String aPath)
            : this()
        {
            this.Path = aPath;

        }
        public ApacheConf()
        {
            locations = new Locations();
        }
        public string Path
        {
            get { return path; }
            set
            {
                   if (System.IO.File.Exists(value))
                {
                    path = value;
                }
                else
                {
                    throw new FileNotFoundException("找不到Apache Conf文件",value);
                }
            }
        }
        public bool parse()
        {
            using (TextReader tr = new StreamReader(Path, Encoding.GetEncoding("GB2312")))
            {
                String txt = tr.ReadToEnd();
                try
                {
                    string strRegex = @"(#(?<topComment>.*)\r\n)*<Location /(?<urlName>\w+)>\s+DAV\s+svn\s+(SVNListParentPath\s+(?<SVNListParentPath>\w*)\s+)?(SVNParentPath\s+(?<SVNParentPath>\S+)\s+)?(AuthType\s+(?<AuthType>\w*)\s+)?(AuthName\s+""(?<AuthName>.*)""\s+)?((?<useAuthUserFile>[#])AuthUserFile\s+(?<AuthUserFile>.*)\r\s+)?(AuthMySQLHost\s+(?<AuthMySQLHost>.+)\r\s+)?(AuthMySQLUser\s+(?<AuthMySQLUser>\w+)\s+)?AuthMySQLPassword\s+(?<AuthMySQLPassword>.*)\r\s+()?(AuthMySQLDB\s+(?<AuthMySQLDB>\w+)\s+)?(AuthMySQLUserTable\s+(?<AuthMySQLUserTable>\w+)\s+)?(AuthMySQLNameField\s+(?<AuthMySQLNameField>\w+)\s+)?(AuthMySQLPasswordField\s+(?<AuthMySQLPasswordField>\w+)\s+)?(AuthMySQLPwEncryption\s+(?<AuthMySQLPwEncryption>\w+)\s+)?(AuthzSVNAccessFile\s+(?<AuthzSVNAccessFile>\S+)\s+)?(?<RequireValidUser>(Require\s+valid-user)\s+)?((#(?<autoVersionComment>.*)\r\s+)?SVNAutoversioning\s+(?<SVNAutoversioning>\w*)\s+ModMimeUsePathInfo\s+(?<ModMimeUsePathInfo>\w*)\s+)?</Location>";
                    Regex regex = new Regex(strRegex, RegexOptions.Multiline);
                    MatchCollection matches = regex.Matches(txt);
                    GroupCollection gc;
                    string strTmp;
                    Location loc;
                    foreach (Match match in matches)
                    {
                        gc = match.Groups;

                        loc = new Location();

                        strTmp = gc["topComment"].Value;
                        loc.topComment = strTmp;

                        strTmp = gc["urlName"].Value;
                        loc.urlName = strTmp;

                        strTmp = gc["SVNListParentPath"].Value;
                        loc.SVNListParentPath = (strTmp.ToLower()=="on");

                        strTmp = gc["SVNParentPath"].Value;
                        loc.SVNParentPath = strTmp;

                        strTmp = gc["AuthType"].Value;
                        loc.AuthType = (lAuthType)(Enum.Parse(typeof(lAuthType), strTmp, true));

                        strTmp = gc["AuthName"].Value;
                        loc.AuthName = strTmp;

                        strTmp = gc["useAuthUserFile"].Value;
                        loc.useAuthUserFile = (strTmp.ToLower() != "#");

                        strTmp = gc["AuthUserFile"].Value;
                        loc.AuthUserFile = strTmp;

                        strTmp = gc["AuthMySQLHost"].Value;
                        loc.AuthMySQLHost = strTmp;

                        strTmp = gc["AuthMySQLUser"].Value;
                        loc.AuthMySQLUser = strTmp;

                        strTmp = gc["AuthMySQLPassword"].Value;
                        loc.AuthMySQLPassword = strTmp;

                        strTmp = gc["AuthMySQLDB"].Value;
                        loc.AuthMySQLDB = strTmp;

                        strTmp = gc["AuthMySQLUserTable"].Value;
                        loc.AuthMySQLUserTable = strTmp;

                        strTmp = gc["AuthMySQLNameField"].Value;
                        loc.AuthMySQLNameField = strTmp;

                        strTmp = gc["AuthMySQLPasswordField"].Value;
                        loc.AuthMySQLPasswordField = strTmp;

                        strTmp = gc["AuthMySQLPasswordField"].Value;
                        loc.AuthMySQLPasswordField = strTmp;

                        strTmp = gc["AuthMySQLPwEncryption"].Value;
                        loc.AuthMySQLPwEncryption = (lEncryption)(Enum.Parse(typeof(lEncryption), strTmp, true));

                        strTmp = gc["AuthzSVNAccessFile"].Value;
                        loc.AuthzSVNAccessFile = strTmp;

                        strTmp = gc["RequireValidUser"].Value;
                        loc.RequireValidUser = (strTmp.Length > 0);

                        strTmp = gc["autoVersionComment"].Value;
                        loc.autoVersionComment = strTmp;
                        if (strTmp.Length > 0)
                        {
                            strTmp = gc["autoVersionComment"].Value;
                        }

                        strTmp = gc["SVNAutoversioning"].Value;
                        loc.SVNAutoversioning = (strTmp.ToLower() == "on");

                        strTmp = gc["ModMimeUsePathInfo"].Value;
                        loc.ModMimeUsePathInfo = (strTmp.ToLower() == "on");

                        locations.Add(loc);
                    }
                    locations.Sort();
                }
                catch
                {
                    return false;
                }
            }
            return true;
        }
        public bool parse(string path)
        {
            Path = path;
            return parse();
        }

        public bool save()
        {
            return save(this.Path);
        }
        public bool save(string toPath)
        {
            try
            {
                String txt = ToString();
                using (TextWriter tw = new StreamWriter(toPath,false,Encoding.GetEncoding("GB2312")))
                {
                    tw.Write(txt);
                }

                return true;
            }
            catch
            {
                return false;
            }
        }

        public override String ToString()
        {
            String txt;
            using (TextReader tr = new StreamReader(Path, Encoding.GetEncoding("GB2312")))
            {
                txt = tr.ReadToEnd();
            }
            if (locations.Count > 0)
            {
                string strRegex = @"(?:(?:(?:#.*\r\n)?<Location /.+>\s+DAV svn\s+(?:\S*\s*)+</Location>(?:(?:\r\n*)\s*)*))";
                Regex regex = new Regex(strRegex, RegexOptions.Multiline);
                string[] strs = regex.Split(txt);
                //if (strs.Length > 2) return false;
                txt = strs[0];

                txt += locations.ToString();
                if (2 == strs.Length)
                {
                    txt += strs[1];
                }
            }
            return txt;
        }
    }
}
